www.gusucode.com > VC++ douglas道格拉斯算法示例-源码程序 > VC++ douglas道格拉斯算法示例-源码程序/code/myAPI.cpp
//Download by http://www.NewXing.com #include "stdafx.h" #include "myAPI.h" #include <math.h> void WINAPI DouglasPeuckerDataCompress(POINT* orgPoint,int nPt, CUIntArray& aPtNum,double tolerance) { CUIntArray NumPoint; aPtNum.RemoveAll(); ColInfoArray aStack; COLINFO from_to; double deepth; int nSt,nEd; int i,j,tempNum; nSt = 0; nEd = nPt-1; NumPoint.Add(nSt); NumPoint.Add(nEd); BOOL flag = TRUE; CPoint hhh; do { tempNum = GetMaxArcLength(orgPoint,nPt,nSt,nEd,deepth); if(deepth>tolerance) { NumPoint.Add(tempNum); from_to.from = tempNum; from_to.to = nEd; aStack.Add(from_to); nEd = tempNum; } else { int numStack = aStack.GetSize(); if(numStack==0) flag = FALSE; else { from_to = aStack.GetAt(numStack-1); nSt = from_to.from; nEd = from_to.to; aStack.RemoveAt(numStack-1); } } }while(flag); int numPt = NumPoint.GetSize(); int minNum,k; for(j=0;j<numPt;j++) { minNum = NumPoint.GetAt(0); k = 0; for(i=1;i<NumPoint.GetSize();i++) { if(minNum>(int)NumPoint.GetAt(i)) { minNum = NumPoint.GetAt(i); k = i; } } aPtNum.Add(minNum); if (k<NumPoint.GetSize()) { NumPoint.RemoveAt(k); } } } int WINAPI GetMaxArcLength(POINT* point,int nPt,int nStart,int nEnd,double& maxLength) { int i,numPoint; double dee = 0; maxLength = 0; numPoint = nStart; POINT pt,LinePt1,LinePt2; // double dis; for(i=nStart+1;i<nEnd;i++) { //double a,b,c; //a = (double)point[nEnd].y-(double)point[nStart].y; //b = (double)point[nStart].x-(double)point[nEnd].x; //c = -b*((double)point[nStart].y)-a*((double)point[nStart].x); //dee = fabs(a*((double)point[i].x)+b*((double)point[i].y)+c)/sqrt(a*a+b*b); //== Modified by Ai, August 14, 2003 , HongKong pt=point[i]; LinePt1=point[nEnd]; LinePt2=point[nStart]; dee=DistancePointToLine(pt,LinePt1,LinePt2); if(maxLength<dee) { maxLength = dee; numPoint = i; } } return numPoint; } double WINAPI DistancePointToLine(POINT pt,POINT LinePt1,POINT LinePt2) { INTERSECT inter; fLINE line; DPOINT Apt; Apt.x=(float)pt.x; Apt.y=(float)pt.y; line.sx=(float)LinePt1.x; line.sy=(float)LinePt1.y; line.ex=(float)LinePt2.x; line.ey=(float)LinePt2.y; DisPtToLine(&inter,Apt,line); if(inter.In) return (double)inter.Dis; else { double dis1 = DistanceBetweenTwoPoints(pt,LinePt1); double dis2 = DistanceBetweenTwoPoints(pt,LinePt2); return (dis1 < dis2)?dis1:dis2; } } double WINAPI DistanceBetweenTwoPoints(DPOINT pt1,DPOINT pt2) { double A = pt1.x-pt2.x; double B = pt1.y-pt2.y; return sqrt(A*A+B*B); } void WINAPI DisPtToLine(INTERSECT* Inters,DPOINT Apt,fLINE line) { float A,B,C; DPOINT pt; A=line.sy-line.ey; B=line.ex-line.sx; if(fabs(A)<0.00001 && fabs(B)<0.00001) { Inters->pt.x=line.sx; Inters->pt.y=line.sy; Inters->In=TRUE; Inters->Dis=DistanceBetweenTwoPoints(Apt,Inters->pt); return; } C=(line.sx-line.ex)*line.sy+(line.ey-line.sy)*line.sx; double dis = A*Apt.x+B*Apt.y+C; Inters->Dis=(float)fabs(dis)/(float)sqrt(A*A+B*B); pt.x=(B*B*Apt.x-A*B*Apt.y-A*C)/(A*A+B*B); pt.y=(A*A*Apt.y-A*B*Apt.x-B*C)/(A*A+B*B); Inters->pt.x=pt.x; Inters->pt.y=pt.y; if((pt.x>min(line.sx,line.ex) && pt.x<max(line.sx,line.ex))|| (pt.y>min(line.sy,line.ey) && pt.y<max(line.sy,line.ey))) Inters->In=TRUE; else Inters->In=FALSE; return; } double WINAPI DistanceBetweenTwoPoints(POINT pt1,POINT pt2) { double A = (double)pt1.x-(double)pt2.x; double B = (double)pt1.y-(double)pt2.y; return sqrt(A*A+B*B); }